﻿using System;
using System.Collections.Generic;
using JWT;
using JWT.Algorithms;
using JWT.Serializers;

namespace Teamwish.Domain.Common
{
    /// <summary>
    /// Token相关操作类
    /// </summary>
    public class TokenHelper
    {
        public static string SecretKey = "tokenjiami";//这个服务端加密秘钥 属于私钥

        public static string GenToken(TokenInfo M,int hours=2)
        {

            var jwtcreated =Math.Round((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds + 5);
            var jwtcreatedOver =Math.Round((DateTime.UtcNow.AddHours(hours) - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds + 5);
            var payload = new Dictionary<string, dynamic>
                {
                    {"iss", M.iss},//非必须。issuer 请求实体，可以是发起请求的用户的信息，也可是jwt的签发者。
                    {"iat", jwtcreated},//非必须。issued at。 token创建时间，unix时间戳格式
                    {"exp", jwtcreatedOver},//非必须。expire 指定token的生命周期。unix时间戳格式
                    {"aud", M.aud},//非必须。接收该JWT的一方。
                    {"sub", M.sub},//非必须。该JWT所面向的用户
                    {"jti", M.jti},//非必须。JWT ID。针对当前token的唯一标识
                    {"UserId", M.UserId},//自定义字段 用于存放当前登录人登录权限信息
                    {"UserCode", M.UserCode},//自定义字段 用于存放当前登录人登录权限信息
                    {"UserName", M.UserName},//自定义字段 用于存放当前登录人账户信息
                    {"UserPwd", M.UserPwd},//自定义字段 用于存放当前登录人登录密码信息
                    {"UserRole", M.UserRole},//自定义字段 用于存放当前登录人登录权限信息
                };
            IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
            IJsonSerializer jsonSerializer = new JsonNetSerializer();
            IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();

            IJwtEncoder encoder = new JwtEncoder(algorithm,jsonSerializer,urlEncoder);
            return encoder.Encode(payload, SecretKey);
        }

        public static IDictionary<string, dynamic> DecodeToken(string token)
        {
            try
            {

                IJsonSerializer serializer = new JsonNetSerializer();
                IDateTimeProvider provider = new UtcDateTimeProvider();
                IJwtValidator validator = new JwtValidator(serializer, provider);
                IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
                IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder);

                //var userInfo = decoder.DecodeToObject<UserInfo>(token, CommonToken.SecretKey, verify: true);//token为之前生成的字符串
                var dictPayload = decoder.DecodeToObject(token, TokenHelper.SecretKey, verify: false) as IDictionary<string, dynamic>;

                //var dictPayload = JWT.JwtDecoder.DecodeToObject(token, CommonToken.SecretKey) as IDictionary<string, dynamic>;
                return dictPayload;
            }
            catch (Exception ex)
            {
                return null;
            }
        }
    }

    public class TokenInfo
    {
        public TokenInfo()
        {
            iss = "签发者信息";
            aud = "http://example.com";
            sub = "";
            jti = DateTime.Now.ToString("yyyyMMddhhmmss");            
            UserName = "";
            UserPwd = "";
            UserRole = "";
            UserCode = "";
        }

        public TokenInfo(string userId,string userName,string wxName,string wxCode,string roles,DateTime expired)
        {
            iss = userName;
            aud = "http://example.com";
            sub = "HomeCare.VIP";
            jti = expired.ToString("yyyyMMddhhmmss");
            UserId = userId;
            UserName = userName;
            UserRole = roles;
            WxName = wxName;
            UserCode = wxCode;
        }

        public string iss { get; set; }
        public string aud { get; set; }
        public string sub { get; set; }
        public string jti { get; set; }
        public string UserId { get; set; }
        public string UserName { get; set; }
        public string UserPwd { get; set; }
        public string UserRole { get; set; }
        public string UserCode { get; set; }
        public string WxName { get; set; }
        
    }
}